# -*- coding: UTF-8 -*-

# Copyright (C) 2009 Daniele Favara.
# Written by Daniele Favara <daniele@zeroisp.com>.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA


import os
import transaction
from tg import config, session, request
from tgext.zeroisp import model

from tgext.zeroisp.lib.picasa_google_com import PicasaGoogleCom

try:
    PATH_UPLOAD = os.path.join(config['pylons.paths']['static_files'],
                           'uploads')
except:
    pass
    #print 'ERROR in PATH_UPLOAD'

from tgext.zeroisp.lib.utils import get_picasa
from tgext.zeroisp import get_i18nicons, get_i18n

from tg import config, session, request
from sqlalchemy import *
import xml.dom.minidom

INIT_DB_PATH = config.get('tgext.zeroisp.init_db_path')

def get_xml(path):
    return xml.dom.minidom.parse(path)

def getText(nodelist):
    rc = ""
    for node in nodelist:
        if node.nodeType == node.TEXT_NODE:
            rc = rc + node.data
    return rc

def get_value(o, form):
    value = {}
    for field in form.fields():
        if field.name:
            if hasattr(o, field.name):
                value[field.name] = getattr(o, field.name)
    return value

def set_value(o, kw):
    for k, v in kw.iteritems():
        if hasattr(o, k):
            setattr(o, k, v)
    return o

def get_init1(item):
    values = {}
    subitems = []
    for subitem in item.childNodes:
        if subitem.nodeType == subitem.ELEMENT_NODE :
            if not subitem.hasChildNodes():
                value = subitem.getAttribute('value')
                if value == u'True':
                    value = True
                elif value == u'False':
                    value = False
                values[subitem.tagName] = value
            else:
                #if subitem.tagName in ['fieldkey', 'team_user']:
                subitems.append(subitem)
    return values, subitems

def _io_teampage(team, **kw):
    if not team.page:
        teampage = model.TeamPage()
        post = model.Post()
        post = set_value(post, kw)
        post.teampage.append(teampage)
        team.teampage.append(teampage)
        model.DBSession.flush()
        model.DBSession.add(team)
    else:
        post = team.page
        post = set_value(post, kw)
        model.DBSession.flush()
        model.DBSession.add(post)

def init_user(item):
    values, subitems = get_init1(item)
    try:
        user = model.DBSession.query(model.User).filter_by(user_name=values['user_name']).one()
    except:
        user = model.User(user_name=values['user_name'])
    user = set_value(user, values)
    #model.DBSession.flush()
    model.DBSession.add(user)

def init_address(item):
    values, subitems = get_init1(item)
    team = model.DBSession.query(model.Team).filter_by(team_alias=values['team_alias']).one()
    if team.page:
        if not team.address:
            google_address = model.GoogleAddress()
            google_address = set_value(google_address, values)
            google_address.posts.append(team.page)
        else:
            google_address = team.address
            google_address = set_value(google_address, values)
        #model.DBSession.flush()
        model.DBSession.add(google_address)

def init_team(item):
    values, subitems = get_init1(item)
    try:
        team = model.DBSession.query(model.Team).filter_by(team_alias=values['team_alias']).one()
    except:
        team = model.Team(team_alias=values['team_alias'])
    team = set_value(team, values)
    team_child_of=values.get('team_child_of')
    if team_child_of:
        parent = model.DBSession.query(model.Team).filter_by(team_alias=team_child_of).one()
        team.parent_team = parent
    _io_teampage(team, **dict(team_alias=team.team_alias, post_title=values.get('team_display_name'), post_description=''))

    #model.DBSession.flush()
    model.DBSession.add(team)
    for item in subitems:
        values, subitems = get_init1(item)
        if item.tagName == 'team_user':
            user = model.DBSession.query(model.User).filter_by(user_name=values['user_name']).one()
            if not user in team.users:
                team.users.append(user)
            try:
                membership = model.DBSession.query(model.Membership).filter_by(user_id=user.user_id,
                                                                           team_id=team.team_id).one()
            except:
                membership = model.Membership(team,user)
            membership.role = values['role']
            model.DBSession.flush()
            model.DBSession.add(membership)
        elif item.tagName == 'company':
            if not team.company:
                company = model.Company()
            else:
                company = team.company[0]
            company = set_value(company, values)
            team.company.append(company)
            #model.DBSession.flush()
            model.DBSession.add(company)




def init_category(item):
    values, subitems = get_init1(item)
    try:
        category = model.DBSession.query(model.Category).filter_by(category_name=values['category_name']).one()
    except:
        category = model.Category(category_name=values['category_name'])

    category = set_value(category, values)
    #model.DBSession.flush()
    model.DBSession.add(category)

def init_detail(item):
    values, subitems = get_init1(item)
    try:
        detail = model.DBSession.query(model.Detail).filter_by(detail_alias=values['detail_alias']).one()
    except:
        detail = model.Detail(detail_alias=values['detail_alias'])
    category = model.DBSession.query(model.Category).filter_by(category_name=values['detail_category_name']).one()
    values['detail_category_id'] = category.category_id
    detail = set_value(detail, values)
    for item in subitems:
        values, s = get_init1(item)
        try:
            fieldkey = model.DBSession.query(model.FieldKey).filter_by(fieldkey_name=values['fieldkey_name']).one()
        except:
            fieldkey = model.FieldKey(fieldkey_name=values['fieldkey_name'])

        fieldkey = set_value(fieldkey,values)
        #model.DBSession.flush()
        detail.fieldkeys.append(fieldkey)
        model.DBSession.add(fieldkey)

    #model.DBSession.flush()
def get_xmlobjs():
    ret = []
    if os.path.exists(INIT_DB_PATH):
        listdir=os.listdir(INIT_DB_PATH)
        listdir.sort()
        for filename in listdir:
            xmlpath=os.path.join(INIT_DB_PATH, filename)
            if os.path.isfile(xmlpath) and xmlpath.endswith('.xml'):
                print xmlpath
                xml_obj = get_xml(xmlpath)
                ret.append(xml_obj)
    return ret

def init_db():
    xml_objs=get_xmlobjs()
    for xml_obj in xml_objs:
        for item in xml_obj.childNodes:
            if item.tagName == 'zeroisp':
                for subitem in item.childNodes:
                    if subitem.nodeType == subitem.ELEMENT_NODE :
                        if subitem.tagName == 'category':
                            try:
                                init_category(subitem)
                                print "Category done"
                            except:
                                print "Category ERROR"
                        if subitem.tagName == 'user':
                            try:
                                init_user(subitem)
                                print "User done"
                            except:
                                print "User ERROR"
                        if subitem.tagName == 'team':
                            try:
                                init_team(subitem)
                                print "Team done"
                            except:
                                print "Team ERROR"
                        if subitem.tagName == 'address':
                            try:
                                init_address(subitem)
                                print "Address done"
                            except:
                                print "Address ERROR"
                        if subitem.tagName == 'detail':
                            try:
                                init_detail(subitem)
                                print "Detail done"
                            except:
                                print "Detail ERROR"

def init_locale():
    icons = get_i18nicons()
    from babel.core import UnknownLocaleError
    for i in icons:
        try:
            k = get_i18n(i)
            if k:
                try:
                    language = model.DBSession.query(model.Language).filter_by(lang_code=k[0]).one()
                except:
                    language = model.Language(lang_code=k[0])
                language.lang_name=k[1]
                model.DBSession.add(language)
        except UnknownLocaleError:
            pass



def update_password(**kw):
    user= model.DBSession.query(model.User).filter_by(user_name=request.identity['repoze.who.userid']).one()
    user = set_value(user, kw)
    model.DBSession.flush()
    model.DBSession.add(user)
    transaction.commit()

def insert_teampage(**kw):
    user= model.DBSession.query(model.User).filter_by(user_name=request.identity['repoze.who.userid']).one()
    team = model.DBSession.query(model.Team).filter_by(team_alias=kw.get('team_alias')).one()
    if team in user.teams:
        _insert_teampage(team, **kw)
    transaction.commit()

def update_teampage(**kw):
    user= model.DBSession.query(model.User).filter_by(user_name=request.identity['repoze.who.userid']).one()
    team = model.DBSession.query(model.Team).filter_by(team_alias=kw.get('team_alias')).one()
    if team in user.teams:
        _io_teampage(team, **kw)
    transaction.commit()

def update_teamaddress(team_alias, **kw):
    user= model.DBSession.query(model.User).filter_by(user_name=request.identity['repoze.who.userid']).one()
    team = model.DBSession.query(model.Team).filter_by(team_alias=team_alias).one()
    if True:#team in user.teams:
        if team.page:
            if not team.address:
                google_address = model.GoogleAddress(**kw)
                google_address.posts.append(team.page)
            else:
                google_address = team.address
                for k,v in kw.iteritems():
                    if hasattr(google_address, k):
                        setattr(google_address, k, v)
            model.DBSession.flush()
            model.DBSession.add(google_address)
            transaction.commit()

def insert_team(**kw):
    user= model.DBSession.query(model.User).filter_by(user_name=request.identity['repoze.who.userid']).one()
    try:
        team = model.DBSession.query(model.Team).filter_by(team_alias=kw.get('team_alias')).one()
    except:
        team = model.Team(**kw)
        user.teams.append(team)
        model.DBSession.flush()
        model.DBSession.add(user)
        transaction.commit()

def insert_category(**kw):
    category = model.Category()
    category = set_value(category, kw)
    model.DBSession.add(category)
    model.DBSession.flush()
    transaction.commit()

def insert_field(**kw):
    user= model.DBSession.query(model.User).filter_by(user_name=request.identity['repoze.who.userid']).one()
    team = model.DBSession.query(model.Team).filter_by(team_alias=kw.get('team_alias')).one()
    if team in user.teams:
        category = model.DBSession.query(model.Category).filter_by(category_id=kw.get('category_id')).one()
        if category in team.categories:
            fieldkey = model.FieldKey()
            for k,v in kw.iteritems():
                if hasattr(fieldkey, k):
                    setattr(fieldkey, k , v)
            category.fieldkeys.append(fieldkey)
            model.DBSession.add(category)
            model.DBSession.flush()
            transaction.commit()

def insert_keyword(**kw):
    user= model.DBSession.query(model.User).filter_by(user_name=request.identity['repoze.who.userid']).one()
    team = model.DBSession.query(model.Team).filter_by(team_alias=kw.get('team_alias')).one()
    post = model.DBSession.query(model.Post).filter_by(post_id=kw.get('post_id')).one()
    if team in user.teams:
        if post in team.posts:
            try:
                keyword = model.DBSession.query(model.Keyword).filter_by(keyword=kw.get('keyword')).one()
            except:
                keyword = model.Keyword()
            keyword = set_value(keyword, kw)
            post.keywords.append(keyword)
            model.DBSession.add(keyword)
            model.DBSession.flush()
            transaction.commit()

def insert_post(**kw):
    user= model.DBSession.query(model.User).filter_by(user_name=request.identity['repoze.who.userid']).one()
    team = model.DBSession.query(model.Team).filter_by(team_alias=kw.get('team_alias')).one()
    category = model.DBSession.query(model.Category).filter_by(category_id=kw.get('post_category_id')).one()
    if team in user.teams:
        post = model.Post()
        post = set_value(post, kw)
        team.posts.append(post)
        model.DBSession.add(post)
        model.DBSession.flush()
        post_id = post.post_id
        transaction.commit()
        return post_id

def update_post(**kw):
    user= model.DBSession.query(model.User).filter_by(user_name=request.identity['repoze.who.userid']).one()
    team = model.DBSession.query(model.Team).filter_by(team_alias=kw.get('team_alias')).one()
    post = model.DBSession.query(model.Post).filter_by(post_id=kw.get('post_id')).one()
    if team in user.teams:
        if post in team.posts:
            post = set_value(post, kw)
            model.DBSession.flush()
            model.DBSession.add(post)
            transaction.commit()

def insert_post_child(**kw):
    team_alias = kw.get('team_alias')
    parent_id = kw.get('parent_id')
    user= model.DBSession.query(model.User).filter_by(user_name=request.identity['repoze.who.userid']).one()
    team = model.DBSession.query(model.Team).filter_by(team_alias=team_alias).one()
    parent = model.DBSession.query(model.Post).filter_by(post_id=parent_id).one()
    if team in user.teams:
        if parent.post_category in team.categories:
            post = model.Post()
            for k,v in kw.iteritems():
                if hasattr(post, k):
                    setattr(post, k, v)
            parent.post_category.posts.append(post)
            parent.childs.append(post)
            model.DBSession.add(parent)
            model.DBSession.flush()
            post_id = post.post_id
            transaction.commit()
            return post_id

def update_details(team_alias, post_id, detail_id, **kw):
    user= model.DBSession.query(model.User).filter_by(user_name=request.identity['repoze.who.userid']).one()
    team = model.DBSession.query(model.Team).filter_by(team_alias=team_alias).one()
    post = model.DBSession.query(model.Post).filter_by(post_id=post_id).one()
    detail = model.DBSession.query(model.Detail).filter_by(detail_id=detail_id).one()
    if team in user.teams:
        if post.post_category in team.categories:

            for key, val in kw.iteritems():
                fieldkey = model.DBSession.query(model.FieldKey).filter_by(
                                            fieldkey_detail_id=detail.detail_id)
                fieldkey = fieldkey.filter_by(fieldkey_name=key).one()
                try:
                    fieldval=model.DBSession.query(model.FieldVal).filter_by(
                                                fieldval_key_id=fieldkey.fieldkey_id,
                                                fieldval_post_id=post.post_id).one()
                except:
                    fieldval = model.FieldVal()
                    fieldval.fieldval_post_id = post.post_id
                fieldval.fieldval_content = val
                fieldkey.values.append(fieldval)
                model.DBSession.add(fieldval)
            model.DBSession.flush()
            transaction.commit()

def update_post_address(team_alias, post_id, **kw):
    user= model.DBSession.query(model.User).filter_by(user_name=request.identity['repoze.who.userid']).one()
    team = model.DBSession.query(model.Team).filter_by(team_alias=team_alias).one()
    post = model.DBSession.query(model.Post).filter_by(post_id=post_id).one()
    if team in user.teams:
        if post.post_category in team.categories:
            if not post.post_address:
                address = model.GoogleAddress()
                address.posts.append(post)
            else:
                address = post.post_address
            for k,v in kw.iteritems():
                if hasattr(address, k):
                    setattr(address, k, v)

            model.DBSession.flush()
            model.DBSession.add(address)
            transaction.commit()

def insert_album(team_alias, post_id, **kw):
    user= model.DBSession.query(model.User).filter_by(user_name=request.identity['repoze.who.userid']).one()
    team = model.DBSession.query(model.Team).filter_by(team_alias=team_alias).one()
    post = model.DBSession.query(model.Post).filter_by(post_id=post_id).one()
    if team in user.teams:
        if post.post_category in team.categories:
            p = get_picasa()
            if post.post_address:
                p_album = p.insert_album("%s-%s"%(team.team_alias,post.post_title), post.post_title,
                                     location=post.post_address.google_address,
                                     access='private')
                p_album.geo.Point.pos.text = "%s %s"%(post.post_address.google_lat,
                                                  post.post_address.google_lng)
            else:
                p_album = p.insert_album("%s-%s"%(team.team_alias,post.post_title),post.post_title,
                                         access='private')
            p.update_album(p_album)
            album = model.Album()
            album.album_id = p_album.gphoto_id.text
            album.album_thumb = p_album.media.thumbnail[0].url
            album.posts.append(post)
            model.DBSession.add(album)
            model.DBSession.flush()
            transaction.commit()

def update_photo(team_alias, post_id, **kw):
    user= model.DBSession.query(model.User).filter_by(user_name=request.identity['repoze.who.userid']).one()
    team = model.DBSession.query(model.Team).filter_by(team_alias=team_alias).one()
    post = model.DBSession.query(model.Post).filter_by(post_id=post_id).one()
    if team in user.teams:
        if post.post_category in team.categories:
            p = get_picasa()
            album = p.get_album(str(post.post_album_id))
            for photo in album.entry:
                if photo.gphoto_id.text == kw.get('photoid'):
                    photo.title.text = kw.get('title')
                    photo.summary.text = kw.get('summary')
                    p.update_photo(photo)
                    break

def insert_photos(team_alias, post_id, **kw):
    print '='*10, kw , '='*10
    user= model.DBSession.query(model.User).filter_by(user_name=request.identity['repoze.who.userid']).one()
    team = model.DBSession.query(model.Team).filter_by(team_alias=team_alias).one()
    post = model.DBSession.query(model.Post).filter_by(post_id=post_id).one()
    if team in user.teams:
        if post.post_category in team.categories:
            p = get_picasa()
            album = p.get_album(str(post.post_album.album_id))
            for k, v in  kw.iteritems():
                if isinstance(v, list):
                    for i in v:
                        if hasattr(i, 'FieldStorage'):
                            fn = os.path.basename(i.filename)
                            fn = os.path.basename(i.filename)
                            photo_name = os.path.basename(i.filename)
                            p.insert_photo(album, i.file,
                                           title=post.post_title)
                else:
                    p.insert_photo(album, v.file,title=post.post_title)


